package domain

import (
	"gluenet/internal/glue-srvp/domain/aggregate"
	"gluenet/internal/glue-srvp/domain/vo"
	"gluenet/internal/pkg/infra"
	"gluenet/internal/pkg/infra/prepare"
)

// 创建对象，并把对象放入依赖池，架构自动构建依赖
func init() {
	prepare.RegisterService(func() {
		config := NewInstanceDomain()
		prepare.InjectDependency(func() *Instance {
			return config
		})
	})
}

// Instance 应用实例领域，管理应用运行中的实例
type Instance struct {
	InstanceFactory *aggregate.InstanceFactory
}

//func (r *Instance) Stop(guid string) error {
//	return r.InstanceCLI.StopObject(guid)
//}
//
//func (r *Instance) Start(guid string) error {
//	return r.InstanceCLI.StartObject(guid)
//}

// Remove 删除实例
func (r *Instance) Remove(auth infra.AuthInfo, id int64) (interface{}, error) {
	return r.InstanceFactory.DelInstance(auth, id)
}

// Create 创建
func (r *Instance) Create(auth infra.AuthInfo, req vo.CreateInstanceReq) (interface{}, error) {
	ins, err := r.InstanceFactory.AddInstance(auth, req)
	if err != nil {
		return nil, err
	}
	return ins, nil
}

// Create 创建
func (r *Instance) Update(auth infra.AuthInfo, req vo.UpdateInstanceReq) (interface{}, error) {
	return r.InstanceFactory.UptInstance(auth, req)
}

//func (r *Instance) MarkedTag(ObjId, key, value string) error {
//	return r.TagRepo.New(ObjId, key, value)
//}

// FindByUser 查询实例
func (r *Instance) FindBy(auth infra.AuthInfo, query map[string]interface{}) (interface{}, error) {
	ins, err := r.InstanceFactory.Findby(auth, query)
	if err != nil {
		return nil, err
	}
	return ins, nil
}

//func (r *Instance) FindBy(query map[string]interface{}) (interface{}, error) {
//	ins, err := r.InstanceFactory.QueryInstance(query)
//	if err != nil {
//		return nil, err
//	}
//	var insRes = make([]interface{}, len(ins))
//	for index, it := range ins {
//		insRes[index] = it.ShowInfo()
//	}
//	return insRes, nil
//}

func (r *Instance) FindRuntime(auth infra.AuthInfo, query map[string]interface{}) (interface{}, error) {
	return r.InstanceFactory.Runtime(auth, query)
}

func (r *Instance) FindRuntimeChildInfo(auth infra.AuthInfo, query map[string]interface{}) (interface{}, error) {
	return r.InstanceFactory.RuntimeChildInfo(auth, query)
}

//// FindRuntimeBy 查询运行中的实例，下版本遗弃
//func (r *Instance) FindRuntimeBy(admin bool, userId string, query map[string]interface{}) (interface{}, error) {
//	if !admin {
//		query["user_id"] = userId
//	}
//
//	ins, err := r.InstanceFactory.QueryInstance(query)
//	if err != nil {
//		return nil, err
//	}
//	var insRes = make([]interface{}, len(ins)+1)
//	var tags []interface{}
//	for k, it := range ins {
//		obj, err := it.ShowRuntimeInfo()
//		if err != nil {
//			return nil, err
//		}
//		//cfg, err := r.InstanceFactory.GetInstanceConfig(it.ConfigID, it.UserID)
//		//if err != nil {
//		//	return nil, err
//		//}
//		//obj.Version = cfg.Version
//		//obj.Describe = cfg.Describe
//
//		if k == 0 {
//			e := reflect.TypeOf(obj).Elem()
//			num := e.NumField()
//			tags = make([]interface{}, num)
//			for i := 0; i < num; i++ {
//				tags[i] = e.Field(i).Tag.Get(`json`)
//			}
//			insRes[0] = tags
//		}
//
//		var vals = make([]interface{}, len(tags))
//		e := reflect.ValueOf(obj).Elem()
//		for fid := range tags {
//			val := e.Field(fid).Interface()
//			vals[fid] = val
//		}
//		insRes[k+1] = vals
//	}
//	return insRes, nil
//}
//
//// FindRuntimeBy 查询运行中的实例，下版本遗弃
//func (r *Instance) FindRuntimeListBy(admin bool, userId string, query map[string]interface{}) (interface{}, error) {
//	if !admin {
//		query["user_id"] = userId
//	}
//
//	ins, err := r.InstanceFactory.QueryInstance(query)
//	if err != nil {
//		return nil, err
//	}
//	var insRes = make(map[string]interface{}, len(ins))
//	for _, it := range ins {
//		obj, err := it.ShowRuntimeInfo()
//		if err != nil {
//			return nil, err
//		}
//		insRes[obj.GUID] = obj
//	}
//	return insRes, nil
//}

//func (r *Instance) FindByTag(kvs map[string]string, userID string) ([]*entity.Instance, error) {
//	ids, err := r.TagRepo.FindObjects(kvs)
//	if err != nil {
//		return nil, err
//	}
//	var ins = make([]*entity.Instance, len(ids))
//	for i, id := range ids {
//		cfg, err := r.InstanceRepo.Get(id, userID)
//		if err != nil {
//			return nil, err
//		}
//		ins[i] = cfg
//	}
//	return ins, err
//}

// CreateLinks 创建策略和实例的链接，让实例被策略所管理
func (r *Instance) CreateLinks(auth infra.AuthInfo, ControGUID, AppGUID string) (interface{}, error) {
	return r.InstanceFactory.LinkInstance(auth, ControGUID, AppGUID)
}

// CreateLinks 创建策略和实例的链接，让实例被策略所管理
func (r *Instance) InfoStrategy(auth infra.AuthInfo, ControGUID string, AppGUID []string) (interface{}, error) {
	return nil, nil
}

// GetLinks 查看策略调节的应用
func (r *Instance) GetLinks(auth infra.AuthInfo, ControGUID string) (interface{}, error) {
	return r.InstanceFactory.FindInstanceLinks(auth, ControGUID)
}

// GetLinks 查看删除策略所有的调控链接
func (r *Instance) DeleteAllLinks(auth infra.AuthInfo, ControGUID string) error {
	return r.InstanceFactory.DelAllLink(auth, ControGUID)
}

//// SaveReport 火焰图数据存储，下版本遗弃
//func (r *Instance) SaveReport(report *vo.Cprofile) error {
//	return r.InstanceFactory.SaveReport(report)
//}

// Import 导入非平台启动的应用
func (r *Instance) Import(auth infra.AuthInfo, req *vo.ImportInstanceReq) (interface{}, error) {
	return r.InstanceFactory.ImportInstance(auth, req)
}

// DelImport 删除导入应用的数据记录
func (r *Instance) DelImport(auth infra.AuthInfo, guid string) (interface{}, error) {
	return r.InstanceFactory.DelImportInstance(auth, guid)
}

// UpdateInstanceContainer 动态更新应用的容器，应用启动后，可能会自动创建新容器
func (r *Instance) UpdateInstanceContainer(auth infra.AuthInfo) error {
	return r.InstanceFactory.UpdateInstanceContainers(auth)
}

//// GetJaegerProxy 获取应用的jaeger-all-in-one代理url和agent
//func (r *Instance) GetJaegerProxy(guid string) (interface{}, error) {
//	return r.InstanceFactory.JaegerProxy(guid)
//}

func NewInstanceDomain() *Instance {
	domain := &Instance{}
	prepare.FetchDependency(&domain.InstanceFactory)
	return domain
}
